//1）获得绝对路径
//2）根据后缀名执行相应的函数（参数：exports,module,require,__dirname,__filename）
//3）实现缓存
//4）尝试文件的查找
let path = require('path');
let fs = require('fs');
let vm = require('vm');
const wrapper = [
  '(function(exports,module,myRequire,__dirname,__filename){',
  '})'
];
class Module {
  constructor(id) {
    this.id = id;
    this.exports = {};
  }
  load() {
    let ext = path.extname(this.id);
    Module._extensions[ext](this)
  }
  static _extensions = {
    '.js'(module) {
      let script = fs.readFileSync(module.id);
      let funcstr = wrapper[0] + script + wrapper[1];
      let func = vm.runInThisContext(funcstr);
      console.log(func.toString())
      func.call(module.exports, module.exports, module, myRequire, __dirname, __filename);
    },
    '.json'(module) {
      let script = fs.readFileSync(module.id, 'utf-8');
      module.exports = JSON.parse(script);
    }
  }
  static _cache = {}
  static getabsPath(pathname) {

    let abspath = path.join(__dirname, pathname), result = null;
    try {
      fs.accessSync(abspath);
      result = abspath;
    } catch (e) {
      let exts = Object.keys(Module._extensions);
      exts.some(ext => {
        try {
          fs.accessSync(abspath + ext);
          result = abspath + ext;
          return true;
        } catch (e) {

        }
      })
    }
    return result;
  }
}
function myRequire(pathname) {
  let abspath = Module.getabsPath(pathname);
  if (abspath == null) {
    throw new Error(`file not found: ${pathname}`);
  }
  if (Module._cache[abspath]) {
    return Module._cache[abspath];
  }
  let module = new Module(abspath);
  Module._cache[abspath] = module;
  module.load();
  return module.exports;
}


let test = myRequire("./a.js");
console.log(test); // 111 
